package com.baseandroid.baidutts;

import android.os.Handler;

import com.baidu.tts.client.SpeechSynthesizer;
import com.baidu.tts.client.SpeechSynthesizerListener;
import com.baidu.tts.client.TtsMode;
import com.baseandroid.config.Global;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class BaiduTts {

    protected NonBlockSyntherizer mNonBlockSyntherizer;
    protected String offlineVoice = OfflineResource.VOICE_FEMALE;
    protected String appId = "10780175";
    protected String appKey = "EW5HjkbiYYDFblTI4tLfw3cg";
    protected String secretKey = "9b09950b93888633b4340ddc7aab46d7";
    protected TtsMode ttsMode = TtsMode.MIX;
    protected volatile boolean ttsInitSuccess = false;

    private final List<Runnable> myDeferredActions = new LinkedList<Runnable>();

    public static BaiduTts instance = null;

    public static BaiduTts getInstance() {
        if (instance == null) {
            synchronized (BaiduTts.class) {
                if (instance == null) {
                    instance = new BaiduTts();
                }
            }
        }
        return instance;
    }

    public void initialTts(Handler mainHandler) {
        Map<String, String> params = getParams();
        SpeechSynthesizerListener listener = new UiMessageListener(mainHandler);
        InitConfig initConfig = new InitConfig(appId, appKey, secretKey, ttsMode, params, listener);
        mNonBlockSyntherizer = new NonBlockSyntherizer(Global.getContext(), initConfig, mainHandler);
    }

    protected Map<String, String> getParams() {
        Map<String, String> params = new HashMap<String, String>();
        // 以下参数均为选填
        // 设置在线发声音人： 0 普通女声（默认） 1 普通男声 2 特别男声 3 情感男声<度逍遥> 4 情感儿童声<度丫丫>
        params.put(SpeechSynthesizer.PARAM_SPEAKER, "0");
        // 设置合成的音量，0-9 ，默认 5
        params.put(SpeechSynthesizer.PARAM_VOLUME, "9");
        // 设置合成的语速，0-9 ，默认 5
        params.put(SpeechSynthesizer.PARAM_SPEED, "5");
        // 设置合成的语调，0-9 ，默认 5
        params.put(SpeechSynthesizer.PARAM_PITCH, "5");

        params.put(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer.MIX_MODE_HIGH_SPEED_SYNTHESIZE);
        // 该参数设置为TtsMode.MIX生效。即纯在线模式不生效。
        // MIX_MODE_DEFAULT 默认 ，wifi状态下使用在线，非wifi离线。在线状态下，请求超时6s自动转离线
        // MIX_MODE_HIGH_SPEED_SYNTHESIZE_WIFI wifi状态下使用在线，非wifi离线。在线状态下， 请求超时1.2s自动转离线
        // MIX_MODE_HIGH_SPEED_NETWORK ， 2G 3G 4G wifi使用在线合成，其他使用离线合成 ，6s超时
        // MIX_MODE_HIGH_SPEED_SYNTHESIZE, 2G 3G 4G wifi状态下使用在线，其它状态离线。在线状态下，请求超时1.2s自动转离线
        // 离线资源文件， 从assets目录中复制到临时目录，需要在initTTs方法前完成
        OfflineResource offlineResource = createOfflineResource(offlineVoice);
        // 声学模型文件路径 (离线引擎使用), 请确认下面两个文件存在
        params.put(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, offlineResource.getTextFilename());
        params.put(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, offlineResource.getModelFilename());
        return params;
    }

    protected OfflineResource createOfflineResource(String voiceType) {
        OfflineResource offlineResource = null;
        try {
            offlineResource = new OfflineResource(Global.getContext(), voiceType);
        } catch (IOException e) {
            // IO 错误自行处理
            e.printStackTrace();
        }
        return offlineResource;
    }

    public void baiduTtsSpeak(String voiceMessage, String pushId) {
        if (ttsInitSuccess) {
            mNonBlockSyntherizer.speak(voiceMessage, pushId);
        } else {
            synchronized (myDeferredActions) {
                myDeferredActions.add(new Runnable() {
                    @Override
                    public void run() {
                        if (ttsInitSuccess) {
                            mNonBlockSyntherizer.speak(voiceMessage);
                        }
                    }
                });
            }
        }
    }

    public void doneBaiduTtsDeferred() {
        ttsInitSuccess = true;
        List<Runnable> actions;
        synchronized (myDeferredActions) {
            actions = new ArrayList<Runnable>(myDeferredActions);
            myDeferredActions.clear();
        }
        for (Runnable runnable : actions) {
            runnable.run();
        }
    }

    public void release() {
        if (mNonBlockSyntherizer != null) {
            mNonBlockSyntherizer.release();
        }
    }

}
